# -*- coding: utf-8 -*-

from google.appengine.ext import db
from .exception import UserNameDuplicateError, OneUserPerOpenidError, UserNameInvalidError

USER_NAME_VALIDATOR = None


class Parent(db.Model):
    pass

def get_parent():
    return db.Key.from_path('Parent', 'total__parent__', namespace="")


class User(db.Model):
    """
    Immutable `User` model.
    """
    openid = db.StringProperty(required=True)
    
    @property
    def name(self):
        """ """
        return self.key().name()
    
    @classmethod
    def new(cls, name, openid):
        """
        Factory for creating `User` instances.
        """
        return cls(key_name=name, openid=openid, parent=get_parent())
    
    def put(self):
        return db.run_in_transaction(self._put_in_transaction)
    
    @classmethod
    def get_by_name(cls, name):
        """
        Get user by it's name.
        """
        return cls.get_by_key_name(name, parent=get_parent())
    
    @classmethod
    def get_by_openid(cls, openid):
        """
        Get user by it's openid.
        """
        return cls.all(namespace="").ancestor(get_parent()).filter('openid =', openid).get()
    
    def _put_in_transaction(self):
        """ """
        name = self.name
        
        if not USER_NAME_VALIDATOR(name):
            raise UserNameInvalidError(name)
        
        from_db_by_name = db.get(self.key())
        if from_db_by_name:
            raise UserNameDuplicateError(name)
        
        from_db_by_openid = User.get_by_openid(self.openid)
        if from_db_by_openid:
            raise OneUserPerOpenidError()
        
        return super(User, self).put()